#include "glwidget.h"

void GLWidget::drawTranslatePlane(double x, double y, double z, int objectId)
{   
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glTranslatef(offsetX/R*2,-offsetY/R*2,0);
    if (viewMode == CELL_PERSPECTIVE) {
        gluLookAt(2*cos(Phi)*cos(Theta), 2*sin(Theta), 2*sin(Phi)*cos(Theta),
                  0.0,0.0,0.0, 0.0,1.0,0.0);
    } else if (viewMode == CELL_TOP) {
        gluLookAt(2*cos(0.0)*cos(pi/2), 2*sin(pi/2), 2*sin(0.0)*cos(pi/2),
                  0.0,0.0,0.0, 0.0,1.0,0.0);
    } else if (viewMode == CELL_FRONT) {
        gluLookAt(2*cos(0.0)*cos(0.0), 2*sin(0.0), 2*sin(0.0)*cos(0.0),
                  0.0,0.0,0.0, 0.0,1.0,0.0);
    } else if (viewMode == CELL_RIGHT) {
        gluLookAt(2*cos(pi/2)*cos(0.0), 2*sin(0.0), 2*sin(pi/2)*cos(0.0),
                  0.0,0.0,0.0, 0.0,1.0,0.0);
    }
    glPushMatrix();
    if (objectId == 0) {
        glTranslated(glandular->getTranslateX()/R*2.0, glandular->getTranslateY()/R*2.0,
                     glandular->getTranslateZ()/R*2.0);
        glRotated(-Phi*180/pi, 0.0, 1.0, 0.0);
        glRotated(-Theta*180/pi, 1.0, 0.0, 0.0);
    } else if (objectId == 1){
        glTranslated(plane->translateX/R*2.0, plane->translateY/R*2.0,
                     plane->translateZ/R*2.0);
        glRotated(-Phi*180/pi, 0.0, 1.0, 0.0);
        glRotated(-Theta*180/pi, 1.0, 0.0, 0.0);
    } else if (objectId > 1) {
        glTranslated((objects[objectId-2])->getTranslateX()/R*2.0, (objects[objectId-2])->getTranslateY()/R*2.0,
                     (objects[objectId-2])->getTranslateZ()/R*2.0);
        glRotated(-Phi*180/pi, 0.0, 1.0, 0.0);
        glRotated(Theta*180/pi, 0.0, 0.0, 1.0);
    }
    glPushMatrix();

    glEnable(GL_LINE_SMOOTH);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
    glLineWidth(0.5);
    glLoadName(CELL_TRANSLATEPLANE);
    glBegin(GL_POLYGON);
    glColor3f(1.0, 1.0, 0.2);
    glVertex3f(0.0, -0.4, -0.4);
    glVertex3f(0.0, 0.4, -0.4);
    glVertex3f(0.0, 0.4, 0.4);
    glVertex3f(0.0, -0.4, 0.4);
    glEnd();
    glPopMatrix();

    glPopMatrix();

    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
}

void GLWidget::drawTranslatePoint(int objectId)
{
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glTranslatef(offsetX/R*2,-offsetY/R*2,0);
    if (viewMode == CELL_PERSPECTIVE) {
        gluLookAt(2*cos(Phi)*cos(Theta), 2*sin(Theta), 2*sin(Phi)*cos(Theta),
                  0.0,0.0,0.0, 0.0,1.0,0.0);
    } else if (viewMode == CELL_TOP) {
        gluLookAt(2*cos(0.0)*cos(pi/2), 2*sin(pi/2), 2*sin(0.0)*cos(pi/2),
                  0.0,0.0,0.0, 0.0,1.0,0.0);
    } else if (viewMode == CELL_FRONT) {
        gluLookAt(2*cos(0.0)*cos(0.0), 2*sin(0.0), 2*sin(0.0)*cos(0.0),
                  0.0,0.0,0.0, 0.0,1.0,0.0);
    } else if (viewMode == CELL_RIGHT) {
        gluLookAt(2*cos(pi/2)*cos(0.0), 2*sin(0.0), 2*sin(pi/2)*cos(0.0),
                  0.0,0.0,0.0, 0.0,1.0,0.0);
    }
    glPushMatrix();
    if (objectId == 0) {
        glTranslated(glandular->getTranslateX()/R*2.0, 0.0,
                     glandular->getTranslateZ()/R*2.0);
    } else if (objectId == 1){
        glTranslated(plane->translateX/R*2.0, 0.0,
                     plane->translateZ/R*2.0);
    } else if (objectId > 1) {
        glTranslated((objects[objectId-2])->getTranslateX()/R*2.0, 0.0,
                     (objects[objectId-2])->getTranslateZ()/R*2.0);
    }
    glPushMatrix();

    glLoadName(CELL_TRANSLATEPOINT);
    glColor3f(1.0, 0.2, 0.2);
    glRotated(90, 0, 1, 0);
    drawSolidCube(0.01);
    glPopMatrix();

    glPopMatrix();

    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
}

void GLWidget::drawTranslateAxis(double x, double y, double z, int objectId)
{
    glPushMatrix(); //push to only transform the current object
    if (objectId==0) {
        glTranslated(glandular->getTranslateX(), glandular->getTranslateY(), glandular->getTranslateZ());
        glScaled(glandular->getScaleX(), glandular->getScaleY(), glandular->getScaleZ());
    } else if (objectId>1) {
        glTranslated((objects[objectId-2])->getTranslateX(), (objects[objectId-2])->getTranslateY(), (objects[objectId-2])->getTranslateZ());
        glScaled((objects[objectId-2])->getScaleX(), (objects[objectId-2])->getScaleY(), (objects[objectId-2])->getScaleZ());
    }

    /*
    //positions of the control points relative to the object's center
    GLfloat xpos = 0;
    GLfloat ypos = 0;
    GLfloat zpos = 0;

    if (objects[objectId-2]->getType() == CELL_CYLINDER) {
        xpos = objects[objectId-2]->getCylinderRadius();
        ypos = objects[objectId-2]->getCylinderHeight();
        zpos = objects[objectId-2]->getCylinderRadius();
    } else if (objects[objectId-2]->getType() == CELL_CUBE) {
        xpos = objects[objectId-2]->getCubeWidth()/2;
        ypos = objects[objectId-2]->getCubeHeight()/2;
        zpos = objects[objectId-2]->getCubeDepth()/2;
    } else if (objects[objectId-2]->getType() == CELL_OPENCYLINDER) {
        xpos = objects[objectId-2]->getCylinderRadius();
        ypos = objects[objectId-2]->getCylinderHeight();
        zpos = objects[objectId-2]->getCylinderRadius();
    } else if (objects[objectId-2]->getType() == CELL_PLANE) {
        xpos = objects[objectId-2]->getPlaneWidth();
        ypos = objects[objectId-2]->getPlaneLength()/2;
    } else if (objects[objectId-2]->getType() == CELL_SPHERE) {
        xpos = objects[objectId-2]->getSphereRadius();
        ypos = objects[objectId-2]->getSphereRadius();
        zpos = objects[objectId-2]->getSphereRadius();
    } else if (objects[objectId-2]->getType() == CELL_SPHERE) {
        //TODO
    } */

    //Control Points
    GLfloat ctrl1x = 0;
    GLfloat ctrl1y = 0;
    GLfloat ctrl1z = 0;
    GLfloat ctrl2x = 0;
    GLfloat ctrl2y = 0;
    GLfloat ctrl2z = 0;

    if (objects[objectId-2]->getType() == CELL_LINE)
    {
        ctrl1x = objects[objectId-2]->getCtrlPt1X();
        ctrl1y = objects[objectId-2]->getCtrlPt1Y();
        ctrl1z = objects[objectId-2]->getCtrlPt1Z();

        ctrl2x = objects[objectId-2]->getCtrlPt2X();
        ctrl2y = objects[objectId-2]->getCtrlPt2Y();
        ctrl2z = objects[objectId-2]->getCtrlPt2Z();
    }

    glPushMatrix();
    glLoadName(CELL_CTRLPOINT1);
    glColor3d(1.0, 1.0, 0.2); //yellow
    glTranslated(ctrl1x, ctrl1y, ctrl1z);
    drawSolidCube(0.3);
    glPopMatrix();

    glPushMatrix();
    glLoadName(CELL_CTRLPOINT2);
    glColor3d(1.0, 1.0, 0.2); //yellow
    glTranslated(ctrl2x, ctrl2y, ctrl2z);
    drawSolidCube(0.3);
    glPopMatrix();

    //depth translation
    glPushMatrix();
    glLoadName(CELL_TRANSLATEDEPTH);
    glColor3d(1.0, 0.2, 1.0); //magenta
    glTranslated((ctrl1x+ctrl2x)/2, (ctrl1y+ctrl2y)/2, (ctrl1z+ctrl2z)/2);
    drawSolidCube(0.3);
    glPopMatrix();

    glPopMatrix();

    glMatrixMode(GL_MODELVIEW);
}

void GLWidget::drawRotateAxis(double x, double y, double z,  int objectId)
{
    glPushMatrix(); //push to only transform the current object
    if (objectId==0) {
        glTranslated(glandular->getTranslateX(), glandular->getTranslateY(),
                     glandular->getTranslateZ());
        glRotated(glandular->getRotateCtrl(), glandular->getRotateAxisX(), glandular->getRotateAxisY(), glandular->getRotateAxisZ());
        glScaled(glandular->getScaleX(), glandular->getScaleY(), glandular->getScaleZ());
    } else if (objectId>1) {
        glTranslated((objects[objectId-2])->getTranslateX(), (objects[objectId-2])->getTranslateY(),
                     (objects[objectId-2])->getTranslateZ());
        glRotated((objects[objectId-2])->getRotateCtrl(), (objects[objectId-2])->getRotateAxisX(), (objects[objectId-2])->getRotateAxisY(), (objects[objectId-2])->getRotateAxisZ());
        glScaled((objects[objectId-2])->getScaleX(), (objects[objectId-2])->getScaleY(), (objects[objectId-2])->getScaleZ());
    }

    //Calculate the x,y,z coordinates of each of the x,y,z axis handles
    double xHandleX = x;
    double xHandleY = y;
    double xHandleZ = z;

    double yHandleX = x;
    double yHandleY = y;
    double yHandleZ = z;

    double zHandleX = x;
    double zHandleY = y;
    double zHandleZ = z;

    //Coordinates based on the shape of the object
    if (objects[objectId-2]->getType() == CELL_CYLINDER) {
        yHandleX += objects[objectId-2]->getCylinderRadius();
        xHandleY += objects[objectId-2]->getCylinderHeight();
        zHandleZ += objects[objectId-2]->getCylinderRadius();
    }
    else if (objects[objectId-2]->getType() == CELL_CUBE)
    {
        yHandleX += objects[objectId-2]->getCubeWidth()/2;
        xHandleY += objects[objectId-2]->getCubeHeight()/2;
        zHandleZ += objects[objectId-2]->getCubeDepth()/2;
    }
    else if (objects[objectId-2]->getType() == CELL_OPENCYLINDER)
    {
        yHandleX += objects[objectId-2]->getCylinderRadius();
        xHandleY += objects[objectId-2]->getCylinderHeight();
        zHandleZ += objects[objectId-2]->getCylinderRadius();
    }
    else if (objects[objectId-2]->getType() == CELL_PLANE)
    {
        yHandleX += objects[objectId-2]->getPlaneWidth();
        xHandleY += objects[objectId-2]->getPlaneLength()/2;
    }
    else if (objects[objectId-2]->getType() == CELL_SPHERE)
    {
        yHandleX += objects[objectId-2]->getSphereRadius();
        xHandleY += objects[objectId-2]->getSphereRadius();
        zHandleZ += objects[objectId-2]->getSphereRadius();
    }
    else if (objects[objectId-2]->getType() == CELL_LINE)
    {
        xHandleX = objects[objectId-2]->getCtrlPt1X();
        xHandleY = objects[objectId-2]->getCtrlPt1Y();
        xHandleZ = objects[objectId-2]->getCtrlPt1Z();
    }

    //Coordinates after updating the rotation
    double xHandlePoint[4] = {xHandleX, xHandleY, xHandleZ, 1}; //point of the x-axis handle
    double yHandlePoint[4] = {yHandleX, yHandleY, yHandleZ, 1}; //point of the y-axis handle
    double zHandlePoint[4] = {zHandleX, zHandleY, zHandleZ, 1}; //point of the z-axis handle
    double temp[4][4]; //used to store the object's rotation matrix
    double result[4]; //used to store the result in matrix x vector multiplication

    //copy the object's rotation matrix into temp
    for(int i=0; i<4; i++) {
        for(int j=0; j<4; j++) {
            if (selectObject == 0) {
                temp[i][j] = (glandular->newRotateMatrix)[i][j];
            }
            else if (selectObject > 1) {
                temp[i][j] = (objects[objectId-2]->newRotateMatrix)[i][j];
            }
        }
    }

    //Multiply the rotation matrix by the coordinates of the handle to get its new coordinates
    //store it into result and copy it over into the appropriate variables
    CellMath::matMutiplyVector(temp, xHandlePoint, result);
    xHandleX = result[0];
    xHandleY = result[1];
    xHandleZ = result[2];
    CellMath::matMutiplyVector(temp, yHandlePoint, result);
    yHandleX = result[0];
    yHandleY = result[1];
    yHandleZ = result[2];
    CellMath::matMutiplyVector(temp, zHandlePoint, result);
    zHandleX = result[0];
    zHandleY = result[1];
    zHandleZ = result[2];

    glPushMatrix();
    glLoadName(CELL_CTRLPOINT1);
    glColor3d(1.0, 0.2, 0.2); //red
    glTranslated(x, y, z);
    drawSolidCube(0.3);
    glPopMatrix();

    glPushMatrix();
    glLoadName(CELL_CTRLPOINT2);
    glColor3d(1.0, 0.2, 0.2); //red
    glTranslated(xHandleX, xHandleY, xHandleZ);
    drawSolidCube(0.3);
    glPopMatrix();

    glPopMatrix();

    //good practice to return to the modelview matrix mode so you don't need to keep track of the current mode
    glMatrixMode(GL_MODELVIEW);
}

void GLWidget::drawScaleAxis(double x, double y, double z, int objectId)
{
    glPushMatrix(); //push for object's current transformation
    //general transformations based on the object
    if (objectId==0) {
        glTranslated(glandular->getTranslateX(), glandular->getTranslateY(),
                     glandular->getTranslateZ());
        glRotated(glandular->getRotateZ(), 0.0, 0.0, 1.0);
        glRotated(glandular->getRotateY(), 0.0, 1.0, 0.0);
        glRotated(glandular->getRotateX(), 1.0, 0.0, 0.0);
        glScaled(glandular->getScaleX(), glandular->getScaleY(), glandular->getScaleZ());
    } else if (objectId>1) {
        glTranslated((objects[objectId-2])->getTranslateX(), (objects[objectId-2])->getTranslateY(),
                     (objects[objectId-2])->getTranslateZ());
        glRotated((objects[objectId-2])->getRotateZ(), 0.0, 0.0, 1.0);
        glRotated((objects[objectId-2])->getRotateY(), 0.0, 1.0, 0.0);
        glRotated((objects[objectId-2])->getRotateX(), 1.0, 0.0, 0.0);
        glScaled((objects[objectId-2])->getScaleX(), (objects[objectId-2])->getScaleY(), (objects[objectId-2])->getScaleZ());
    }

    //positions of the control points relative to the object's center
    GLfloat xpos = 0;
    GLfloat ypos = 0;
    GLfloat zpos = 0;

    if (objects[objectId-2]->getType() == CELL_CYLINDER) {
        xpos = objects[objectId-2]->getCylinderRadius();
        ypos = objects[objectId-2]->getCylinderHeight();
        zpos = objects[objectId-2]->getCylinderRadius();
    } else if (objects[objectId-2]->getType() == CELL_CUBE) {
        xpos = objects[objectId-2]->getCubeWidth()/2;
        ypos = objects[objectId-2]->getCubeHeight()/2;
        zpos = objects[objectId-2]->getCubeDepth()/2;
    } else if (objects[objectId-2]->getType() == CELL_OPENCYLINDER) {
        xpos = objects[objectId-2]->getCylinderRadius();
        ypos = objects[objectId-2]->getCylinderHeight();
        zpos = objects[objectId-2]->getCylinderRadius();
    } else if (objects[objectId-2]->getType() == CELL_PLANE) {
        xpos = objects[objectId-2]->getPlaneWidth();
        ypos = objects[objectId-2]->getPlaneLength()/2;
    } else if (objects[objectId-2]->getType() == CELL_SPHERE) {
        xpos = objects[objectId-2]->getSphereRadius();
        ypos = objects[objectId-2]->getSphereRadius();
        zpos = objects[objectId-2]->getSphereRadius();
    }

    glPushMatrix(); //push for x-scale
    glLoadName(CELL_SCALEAXISX); //for picking
    glColor3d(1.0, 0.2, 0.2); //red
    glTranslated(x+xpos, y, z);
    drawSolidCube(0.3);
    glPopMatrix();

    glPushMatrix(); //push for y-scale
    glLoadName(CELL_SCALEAXISY); //for picking
    glColor3d(1.0, 0.2, 0.2); //red
    glTranslated(x, y+ypos, z);
    drawSolidCube(0.3);
    glPopMatrix();

    glPushMatrix(); //push for z-scale
    glLoadName(CELL_ROTATEAXISZ); //for picking
    glColor3d(1.0, 0.2, 0.2); //red
    glTranslated(x, y, z+zpos);
    drawSolidCube(0.3);
    glPopMatrix();

    //center yellow area for retain aspect ratio when scaling
    glPushMatrix();
    glLoadName(CELL_SCALEAXISXYZ);
    glColor3d(1.0, 1.0, 0.2); //yellow
    glTranslated(x+xpos, y+ypos, z);
    drawSolidCube(0.3);
    glPopMatrix();

    glPopMatrix();

    //it's good practive to return to this matrix mode so you don't have to keep track of which mode
    glMatrixMode(GL_MODELVIEW);
}

void GLWidget::drawAxis()
{
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    gluPerspective(45,1.0,0.01,1000);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glPushMatrix();
    if (viewMode == CELL_PERSPECTIVE) {
        gluLookAt(2*cos(Phi)*cos(Theta), 2*sin(Theta), 2*sin(Phi)*cos(Theta),
                  0.0,0.0,0.0, 0.0,1.0,0.0);
    } else if (viewMode == CELL_TOP) {
        gluLookAt(2*cos(0.0)*cos(pi/2), 2*sin(pi/2), 2*sin(0.0)*cos(pi/2),
                  0.0,0.0,0.0, 0.0,1.0,0.0);
    } else if (viewMode == CELL_FRONT) {
        gluLookAt(2*cos(0.0)*cos(0.0), 2*sin(0.0), 2*sin(0.0)*cos(0.0),
                  0.0,0.0,0.0, 0.0,1.0,0.0);
    } else if (viewMode == CELL_RIGHT) {
        gluLookAt(2*cos(pi/2)*cos(0.0), 2*sin(0.0), 2*sin(pi/2)*cos(0.0),
                  0.0,0.0,0.0, 0.0,1.0,0.0);
    }
    GLfloat axisLength = 0.5f;
    glLineWidth(2.0);
    glBegin(GL_LINES);
    // draw x axis in red, y axis in green, z axis in blue
    glColor3f(1.0f, 0.2f, 0.2f);
    glVertex3f(0.0f, 0.0f, 0.0f);
    glVertex3f(axisLength, 0.0f, 0.0f);

    glColor3f(0.2f, 1.0f, 0.2f);
    glVertex3f(0.0f, 0.0f, 0.0f);
    glVertex3f(0.0f, axisLength, 0.0f);

    glColor3f(0.2f, 0.2f, 1.0f);
    glVertex3f(0.0f, 0.0f, 0.0f);
    glVertex3f(0.0f, 0.0f, axisLength);

    glEnd();
    glPopMatrix();
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
}

void GLWidget::drawBackground()
{
    glDisable(GL_LIGHTING);
    glDisable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glBegin(GL_QUADS);
    glColor3f(25.0/255.0 ,26.0/255.0, 30.0/255.0);
    glVertex2f(-1.0,-1.0);
    glVertex2f(1.0,-1.0);
    glColor3f(144.0/255.0, 166.0/255.0, 184.0/255.0);
    glVertex2f(1.0, 1.0);
    glVertex2f(-1.0, 1.0);
    glEnd();
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
}

void GLWidget::drawWire()
{
    glPushMatrix();
    glScalef(30, 0, 30);
    glEnable(GL_LINE_SMOOTH);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
    glLineWidth(1.0);
    glBegin(GL_LINES);
    glColor3f(140.0/255.0, 140.0/255.0, 140.0/255.0);
    for (int i=0; i<=40; i++) {
        if (i!=20) {
            glVertex3f(-1.0, 0.0, 0.05*(i-20));
            glVertex3f(1.0, 0.0, 0.05*(i-20));
            glVertex3f(0.05*(i-20), 0.0, -1.0);
            glVertex3f(0.05*(i-20), 0.0, 1.0);
        }
    }
    glEnd();
    glColor3f(0.0, 0.0, 0.0);
    glLineWidth(3.0);
    glBegin(GL_LINES);
    glVertex3f(-1.0, 0.0, 0.0);
    glVertex3f(1.0, 0.0, 0.0);
    glVertex3f(0.0, 0.0, -1.0);
    glVertex3f(0.0, 0.0, 1.0);
    glEnd();
    glPopMatrix();
}

void GLWidget::drawSolidRectangle(double width, double height, double depth)
{
    double w = width/2;
    double h = height/2;
    double d = depth/2;
    glBegin(GL_QUADS);
    glVertex3d( w, h,-d);
    glVertex3d(-w, h,-d);
    glVertex3d(-w, h, d);
    glVertex3d( w, h, d);

    glVertex3d( w,-h, d);
    glVertex3d(-w,-h, d);
    glVertex3d(-w,-h,-d);
    glVertex3d( w,-h,-d);

    glVertex3d( w, h, d);
    glVertex3d(-w, h, d);
    glVertex3d(-w,-h, d);
    glVertex3d( w,-h, d);

    glVertex3d( w,-h,-d);
    glVertex3d(-w,-h,-d);
    glVertex3d(-w, h,-d);
    glVertex3d( w, h,-d);

    glVertex3d(-w, h, d);
    glVertex3d(-w, h,-d);
    glVertex3d(-w,-h,-d);
    glVertex3d(-w,-h, d);

    glVertex3d( w, h,-d);
    glVertex3d( w, h, d);
    glVertex3d( w,-h, d);
    glVertex3d( w,-h,-d);
    glEnd();
}

void GLWidget::drawSolidCube(double length)
{
    double p = length/2;
    glBegin(GL_QUADS);
    glVertex3d( p, p,-p);
    glVertex3d(-p, p,-p);
    glVertex3d(-p, p, p);
    glVertex3d( p, p, p);

    glVertex3d( p,-p, p);
    glVertex3d(-p,-p, p);
    glVertex3d(-p,-p,-p);
    glVertex3d( p,-p,-p);

    glVertex3d( p, p, p);
    glVertex3d(-p, p, p);
    glVertex3d(-p,-p, p);
    glVertex3d( p,-p, p);

    glVertex3d( p,-p,-p);
    glVertex3d(-p,-p,-p);
    glVertex3d(-p, p,-p);
    glVertex3d( p, p,-p);

    glVertex3d(-p, p, p);
    glVertex3d(-p, p,-p);
    glVertex3d(-p,-p,-p);
    glVertex3d(-p,-p, p);

    glVertex3d( p, p,-p);
    glVertex3d( p, p, p);
    glVertex3d( p,-p, p);
    glVertex3d( p,-p,-p);
    glEnd();
}

void GLWidget::drawSolidCone(double height, double radius)
{
    glBegin(GL_TRIANGLE_FAN);
    glVertex3d(0.0, 0.0, height);
    for (int i=0; i<=360; i=i+30) {
        double x = radius*sin((double)i/180*pi);
        double z = radius*cos((double)i/180*pi);
        glVertex3d(x, z, 0.0);
    }
    glVertex3d(0.0, 0.0, radius);
    glEnd();

    glBegin(GL_TRIANGLE_FAN);
    glVertex3d( 0.0, 0.0, 0.0);
    for (int i=0; i<=360; i=i+30) {
        double x = radius*sin((double)i/180*pi);
        double z = radius*cos((double)i/180*pi);
        glVertex3d(x, z, 0.0);
    }
    glVertex3d(0.0, 0.0, radius);
    glEnd();
}

void GLWidget::drawSelectArea(int ax, int ay, int bx, int by)
{
    float wax = (float)(ax-windowWidth/2)/(windowWidth/2);
    float way = -(float)(ay-windowHeight/2)/(windowHeight/2);
    float wbx = (float)(bx-windowWidth/2)/(windowWidth/2);
    float wby = -(float)(by-windowHeight/2)/(windowHeight/2);
    wax = min(max(-1.0f, wax), 1.0f);
    way = min(max(-1.0f, way), 1.0f);
    wbx = min(max(-1.0f, wbx), 1.0f);
    wby = min(max(-1.0f, wby), 1.0f);
    glDisable(GL_LIGHTING);
    glDisable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glEnable(GL_LINE_SMOOTH);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
    glLineWidth(1.0);
    glBegin(GL_LINES);
    glColor3f(1.0 ,1.0, 1.0);
    glVertex2f(wax, way);
    glVertex2f(wax, wby);

    glVertex2f(wax, wby);
    glVertex2f(wbx, wby);

    glVertex2f(wbx, wby);
    glVertex2f(wbx, way);

    glVertex2f(wbx, way);
    glVertex2f(wax, way);
    glEnd();
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
}
